#pragma once

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <functional>

#include "Connection.hpp"
#include "log.hpp"
#include "HandlerConnection.hpp"

// 连接管理器
class Accepter
{
public:
    void AccepterConnection(Connection *conn)
    {
        errno = 0;
        while (true)
        {

            struct sockaddr_in peer;
            socklen_t len = sizeof peer;
            int sockfd = ::accept(conn->Sockfd(), (struct sockaddr *)&peer, &len);
            if (sockfd > 0)
            {
                lg.LogMessage(Info, "get a new link: %d\n", conn->Sockfd());
                SetNonBlock(sockfd);

                auto recver = std::bind(HandlerConnection::recver, std::placeholders::_1);
                auto sender = std::bind(HandlerConnection::sender, std::placeholders::_1);
                auto excepter = std::bind(HandlerConnection::excepter, std::placeholders::_1);

                Connection *new_conn = ConnectionFactory::
                    BuildNormalConnection(sockfd, recver, sender, excepter, EPOLLIN | EPOLLET, conn->R);

                conn->R->AddConnection(new_conn);
            }
            else
            {
                if (errno == EAGAIN) //! 数据没有准备好
                {
                    break;
                }
                else if (errno == EINTR) //! 被信号中断
                {
                    continue;
                }
                else
                {
                    lg.LogMessage(Info, "get a new link: %d\n", conn->Sockfd());
                    break;
                }
            }
        }
    }
};
